package fr.grassaud.hmvc.session;

import java.util.List;
import java.util.Map;

import fr.grassaud.hmvc.event.HMVCEvent;
import fr.grassaud.hmvc.info.TriadInfo;


/**
 * A triad is set of three components : Model, View and Controller 
 * The framework use the triad to invoke methods on each components. 
 * 
 * @author vgrassaud
 *
 */
public interface Triad {

    
    String DEFAULT_NAME ="root";
    
    /**
     * Consumes the given event
     * @param event the event to consume
     * @return <code>true</code> if the event is well consumed, <code>false</code> otherwise
     */
    boolean consumeEvent(HMVCEvent event);

    
    /**
     * Checks if event can be consumed by this triad
     * @param event the event to consume
     * @return <code>true</code> if the event can be consumed, <code>false</code> otherwise
     */
    boolean canConsumeEvent(HMVCEvent event);

    
    /**
     * Returns all triads children of this triad
     * @return all triads children of this triad, returns an empty map if none
     */
    Map<String, Triad> getChildren();

    
    /**
     * Returns the controller component of this triad
     * @return the controller component of this triad. cannot return <code>null</code> if instantiate method was called
     */
    <T> T getController();

    
    /**
     * Returns the model component of this triad
     * @return the model component of this triad, can return <code>null</code> if there is no model declared for this triad
     */
    <T> T getModel();

    /**
     * Returns the view component of this triad
     * @return the view component of this triad. Cannot return <code>null</code> if instantiate method was called
     */
    <T> T getView();

    
    /**
     * Sets the triad parent of this triad
     * @param parent the triad that will be the parent of this triad
     */
    void setParent(Triad parent);

    
    /**
     * Returns the parent of this triad. 
     * @return the parent of this triad. can return <code>null</code>
     */
    Triad getParent();

    /**
     * Checks if the given object is a component of this triad
     * @param component the component to check if it belongs of this triad
     * @return <code>true</code> if the component belongs this triad, <code>false</code> otherwise
     */
    boolean hasComponent(Object component);

    /**
     * Returns the list of triad that have the given controller class. 
     * @param controllerClass the controller class of the triad 
     * @return a list of triad that have as controller the given controller class
     */
    List<Triad> getTriadWithController(Class<?> controllerClass);

    
    /**
     * Instantiate this triad. Creates each component of this triad. 
     * Instantiates also all chidren. Note that children are not instantiate in a specific order
     */
    void instantiate();
    
    /**
     * Returns the meta information of this triad. The meta information are read from the controller class of this triad
     * @return the meta information of this triad
     */
     TriadInfo getTriadInfo();
     
     
     /**
      * Release this triad and  all children of this triad. Note children are not release in a specific order.
      * The release of a triad is done on specific hmvc event with. 
      * @param event the event that send the demand of release
      */
     void release(HMVCEvent event);
     
     /**
      * Returns the name of this triad. If the triad has not parent, the name will be set to root, <code>{@link #DEFAULT_NAME}</code>
      * @return the name of this triad If the triad has not parent, the name will be set to  root,  <code>{@link #DEFAULT_NAME}</code>
      */
     String getName();
     
     /**
      * Removes from this triad the given child triad. 
      * Note that if the triad is not a child of this one, the method will be nothing
      * @param t the triad to remove
      */
     void removeChild(Triad t);
}
